package com.pig4cloud.pig.ads.service.xingtu;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pig4cloud.pig.ads.pig.mapper.xingtu.XingtuOrderDetailMapper;
import com.pig4cloud.pig.ads.pig.mapper.xingtu.XingtuOrderMapper;
import com.pig4cloud.pig.ads.pig.mapper.xingtu.XingtuTaskMapper;
import com.pig4cloud.pig.ads.service.TtAccesstokenService;
import com.pig4cloud.pig.ads.utils.OEHttpUtils;
import com.pig4cloud.pig.api.entity.ResponseBean;
import com.pig4cloud.pig.api.entity.TtAccesstoken;
import com.pig4cloud.pig.api.entity.xingtu.XingtuOrder;
import com.pig4cloud.pig.api.entity.xingtu.XingtuOrderDetail;
import com.pig4cloud.pig.api.entity.xingtu.XingtuTask;
import com.pig4cloud.pig.common.core.util.BigDecimalUtils;
import com.pig4cloud.pig.common.core.util.R;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 星图任务表
 * @author  chengang
 * @version  2021-12-13 16:47:48
 * table: xingtu_task
 */
@Log4j2
@Service("xingtuTaskService")
@RequiredArgsConstructor
public class XingtuTaskServiceImpl extends ServiceImpl<XingtuTaskMapper, XingtuTask> implements XingtuTaskService {

	private final XingtuOrderMapper xingtuOrderMapper;
	private final XingtuOrderDetailMapper xingtuOrderDetailMapper;
	private final TtAccesstokenService ttAccesstokenService;

	@Value("${xingtu_task_url:https://ad.oceanengine.com/open_api/2/star/demand/list/}")
	private String xingtuTaskUrl;

	@Value("${xingtu_order_url:https://ad.oceanengine.com/open_api/2/star/demand/order/list/}")
	private String xingtuOrderUrl;

	@Value("${xingtu_order_detail_url:https://ad.oceanengine.com/open_api/2/star/report/order_overview/get/}")
	private String xingtuOrderDetailUrl;


	/**
	 * 目前星图账户很少且任务不多，暂时不开线程
	 *
	 */



	@Override
	public R getTaskList(String param) {
		//param 值为星图账户ID，不为空获取指定星图账户ID的任务列表
		List<TtAccesstoken> accessTokenList = this.getTokenList(param);
		//未加挂过任何星图账户
		if (CollectionUtils.isEmpty(accessTokenList)) {
			XxlJobLogger.log("未加挂过任何星图账户");
			return R.ok(null,"未加挂过任何星图账户");
		}
		accessTokenList.forEach(token -> {
			String accessToken = token.getAccessToken();
			String startId = token.getAdAccount();
			try {
				int page = 1;
				while (true) {

					//构建请求参数MAP
					Map<String, Object> paramMap = Maps.newHashMap();
					paramMap.put("star_id",startId);
					paramMap.put("page",page);
					paramMap.put("page_size",30);

					String resultStr = OEHttpUtils.doGet(xingtuTaskUrl, paramMap, accessToken);
					ResponseBean resBean = JSON.parseObject(resultStr, ResponseBean.class);
					if (resBean != null && "0".equals(resBean.getCode())) {
						JSONObject jsonObj = resBean.getData();
						String listStr = jsonObj.getString("list");
						String page_info = jsonObj.getString("page_info");
//						String listStr = "[{\"component_type\":\"LINK\",\"create_time\":\"2021-12-14 18:22:22\",\"demand_id\":101,\"demand_name\":\"#任务101\",\"universal_settlement_type\":\"FIXED_PRICE\"},{\"component_type\":\"GAME_ANCHOR\",\"create_time\":\"2021-12-14 17:22:22\",\"demand_id\":102,\"demand_name\":\"任务102\",\"universal_settlement_type\":\"CPM\"}]";//jsonObj.getString("list");
//						String page_info = "{\"page\":1,\"page_size\":1,\"total_number\":2,\"total_page\":2}";//jsonObj.getString("page_info");
						// String[] 类型的会转 化为JSON类型的String
						List<XingtuTask> list = JSONObject.parseArray(listStr, XingtuTask.class);
						//存储 xingtu_task
						List<XingtuTask> insertList = Lists.newArrayList();
						list.forEach(task ->{
							task.setAdvertiserId(startId);
							// -1 表示定时器更新
							task.setCreateId(-1L);
							task.setUpdateId(-1L);
							XingtuTask xingtuTask = this.getOne(Wrappers.<XingtuTask>lambdaQuery()
									.eq(XingtuTask::getDemandId,task.getDemandId())
									.eq(XingtuTask::getAdvertiserId,startId));
							if (xingtuTask != null) {
								Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
								//有修改则更新-结算方式变更创建时间不会变
//								if (!task.getTaskCreateTime().equals(xingtuTask.getTaskCreateTime())) {
								LambdaUpdateWrapper<XingtuTask> taskUpdate = new LambdaUpdateWrapper<>();
								taskUpdate.eq(XingtuTask::getDemandId,task.getDemandId())
										  .eq(XingtuTask::getAdvertiserId,startId)
										  .set(XingtuTask::getComponentType,task.getComponentType())
										  .set(XingtuTask::getDemandName,task.getDemandName())
										  .set(XingtuTask::getTaskCreateTime,task.getTaskCreateTime())
										  .set(XingtuTask::getUpdateTime,now)
										  .set(XingtuTask::getUniversalSettlementType,task.getUniversalSettlementType());
									this.update(null,taskUpdate);
//								}
							} else {
								insertList.add(task);
							}
						});
						if (CollectionUtils.isNotEmpty(insertList)) {
							this.saveBatch(insertList);
						}

						JSONObject jsonObject = JSONObject.parseObject(page_info);
						Long total_page = jsonObject.getLong("total_page");
						if (page >= total_page) {
							break;
						}
						page++;
					} else {
						XxlJobLogger.log("获取星图任务列表异常：{},星图账户：{}",resBean.getMessage(),startId);
						log.info("获取星图任务列表异常：{},星图账户：{}",resBean.getMessage(),startId);
						break;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				XxlJobLogger.log("获取星图任务列表异常,星图账户：{}",startId);
				log.info("获取星图任务列表异常,星图账户：{}",startId);
			}
		});
		return R.ok();
	}

	@Override
	public R getTaskOrderList(String param) {
		List<TtAccesstoken> accessTokenList = this.getTokenList(param);
		if (CollectionUtils.isEmpty(accessTokenList)) {
			XxlJobLogger.log("未加挂过任何星图账户");
			return R.ok(null,"未加挂过任何星图账户");
		}
		//获取任务列表--可按一个任务一个订单的场景去过滤已有订单的任务，进而减少数据量--但防止业务变更暂不这样处理
		List<XingtuTask> taskList = this.taskList(param);
		if (CollectionUtils.isNotEmpty(taskList)) {
			taskList.forEach(task -> {
				Map<String,String> accesstokenMap = accessTokenList.stream().collect(Collectors.toMap(TtAccesstoken::getAdAccount, TtAccesstoken::getAccessToken));
				String startId = task.getAdvertiserId();
				String accessToken = accesstokenMap.get(startId);
				String demandId = task.getDemandId();
				try {
					int page = 1;
					while (true) {

						//构建请求参数MAP
						Map<String, Object> paramMap = Maps.newHashMap();
						paramMap.put("star_id",startId);
						paramMap.put("demand_id",demandId);
						paramMap.put("page",page);
						paramMap.put("page_size",30);

						String resultStr = OEHttpUtils.doGet(xingtuOrderUrl, paramMap, accessToken);
						ResponseBean resBean = JSON.parseObject(resultStr, ResponseBean.class);
						if (resBean != null && "0".equals(resBean.getCode())) {
							JSONObject jsonObj = resBean.getData();
							String listStr = jsonObj.getString("list");
							String page_info = jsonObj.getString("page_info");
//							String listStr = "[{\"author_id\":201,\"author_name\":\"#达人201\",\"avatar_uri\":\"http://192.168.1.36:8821/admin/sys-file/readFile/avatar/38b627139af74229bb00457b2e53847c.png\",\"create_time\":\"2021-12-14 17:52:22\",\"demand_id\":101,\"head_image_uri\":\"http://192.168.1.36:8821/admin/sys-file/readFile/avatar/38b627139af74229bb00457b2e53847c.png\",\"order_id\":301,\"title\":\"#作品名称\",\"universal_order_status\":\"FINISHED\",\"video_id\":401,\"item_id\":401,\"video_url\":\"http://192.168.1.36:8821/admin/sys-file/readFile/avatar/38b627139af74229bb00457b2e53847c.png\"},{\"author_id\":202,\"author_name\":\"达人202\",\"avatar_uri\":\"http://192.168.1.36:8821/admin/sys-file/readFile/avatar/38b627139af74229bb00457b2e53847c.png\",\"create_time\":\"2021-12-14 18:52:22\",\"demand_id\":101,\"head_image_uri\":\"http://192.168.1.36:8821/admin/sys-file/readFile/avatar/38b627139af74229bb00457b2e53847c.png\",\"order_id\":302,\"title\":\"作品名称2\",\"universal_order_status\":\"ONGOING\",\"video_id\":402,\"item_id\":402,\"video_url\":\"http://192.168.1.36:8821/admin/sys-file/readFile/avatar/38b627139af74229bb00457b2e53847c.png\"}]";
//							String page_info = "{\"page\":1,\"page_size\":1,\"total_number\":2,\"total_page\":2}";//jsonObj.getString("page_info");

							// String[] 类型的会转 化为JSON类型的String
							List<XingtuOrder> list = JSONObject.parseArray(listStr, XingtuOrder.class);

							list.forEach(order ->{
								order.setAdvertiserId(startId);
								order.setDemandId(demandId);
								// -1 表示定时器更新
								order.setCreateId(-1L);
								order.setUpdateId(-1L);
								XingtuOrder xingtuOrder = xingtuOrderMapper.selectOne(Wrappers.<XingtuOrder>lambdaQuery()
										.eq(XingtuOrder::getDemandId,demandId)
										.eq(XingtuOrder::getOrderId,order.getOrderId())
										.eq(XingtuOrder::getAdvertiserId,startId));
								if (xingtuOrder != null) {
									Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
									order.setUpdateTime(now);
									xingtuOrderMapper.update(order,Wrappers.<XingtuOrder>lambdaUpdate()
											.eq(XingtuOrder::getDemandId,demandId)
											.eq(XingtuOrder::getOrderId,order.getOrderId())
											.eq(XingtuOrder::getAdvertiserId,startId));
								} else {
									//目前一个任务一个订单
									xingtuOrderMapper.insert(order);
								}
							});

							JSONObject jsonObject = JSONObject.parseObject(page_info);
							Long total_page = jsonObject.getLong("total_page");
							if (page >= total_page) {
								break;
							}
							page++;
						} else {
							XxlJobLogger.log("获取星图订单列表异常：{},星图账户：{},任务ID：{}",resBean.getMessage(),startId,demandId);
							log.info("获取星图订单列表异常：{},星图账户：{},任务ID：{}",resBean.getMessage(),startId,demandId);
							break;
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
					XxlJobLogger.log("获取星图订单列表异常,星图账户：{},任务ID：{}",startId,demandId);
					log.info("获取星图订单列表异常,星图账户：{},任务ID：{}",startId,demandId);
				}
			});
		}
		return R.ok();
	}

	/**
	 * 暂不支持指定星图账户
	 * @param param
	 * @return
	 */
	@Override
	public R getTaskOrderDetail(String param) {
		List<TtAccesstoken> accessTokenList = this.getTokenList(param);
		if (CollectionUtils.isEmpty(accessTokenList)) {
			XxlJobLogger.log("未加挂过任何星图账户");
			return R.ok(null,"未加挂过任何星图账户");
		}
		//获取订单列表--可按订单状态进行过滤,进而减少数据量,待明确订单的含义
		List<XingtuOrder> orderList = this.orderList(param);
		if (CollectionUtils.isNotEmpty(orderList)) {
			orderList.forEach(order -> {
				Map<String,String> accesstokenMap = accessTokenList.stream().collect(Collectors.toMap(TtAccesstoken::getAdAccount, TtAccesstoken::getAccessToken));
				String startId = order.getAdvertiserId();
				String accessToken = accesstokenMap.get(startId);
				String demandId = order.getDemandId();
				String orderId = order.getOrderId();
				try {
					//构建请求参数MAP
					Map<String, Object> paramMap = Maps.newHashMap();
					paramMap.put("star_id",startId);
					paramMap.put("order_id",orderId);
					String resultStr = OEHttpUtils.doGet(xingtuOrderDetailUrl, paramMap, accessToken);
					ResponseBean resBean = JSON.parseObject(resultStr, ResponseBean.class);
					if (resBean != null && "0".equals(resBean.getCode())) {
						JSONObject dataObj = resBean.getData();
//						JSONObject dataObj = JSONObject.parseObject("{\"comment\":{\"high_frequency_words\":[\"AAA\",\"BBB\"],\"neg_rate\":1110,\"neu_rate\":2220,\"pos_rate\":3330},\"convert\":{\"click\":8888,\"ctr\":2990,\"show\":15000},\"cost_effectiveness\":{\"cpm\":48000,\"play\":1000,\"price\":8989898989},\"creative\":{\"finish_rate\":3020,\"five_s_play_rate\":1000,\"play_rate\":5090},\"spread\":{\"comment\":55555,\"like\":9999,\"play\":4564564,\"share\":4545},\"update_time\":\"2021-12-14 18:25:59\"}");
						//构建insert对象
						XingtuOrderDetail orderDetail = new XingtuOrderDetail();
						orderDetail.setAdvertiserId(startId);
						orderDetail.setDemandId(demandId);
						orderDetail.setOrderId(orderId);
						// -1 表示定时器更新
						orderDetail.setCreateId(-1L);
						orderDetail.setUpdateId(-1L);
						//舆情表现
						JSONObject comment = dataObj.getJSONObject("comment");
						orderDetail.setHighFrequencyWords(comment.getString("high_frequency_words"));
						orderDetail.setNegRate(comment.getString("neg_rate"));
						orderDetail.setNeuRate(comment.getString("neu_rate"));
						orderDetail.setPosRate(comment.getString("pos_rate"));
						//转化表现
						JSONObject convert = dataObj.getJSONObject("convert");
						orderDetail.setConvertClick(convert.getString("click"));
						orderDetail.setConvertCtr(convert.getString("ctr"));
						orderDetail.setConvertShow(convert.getString("show"));
						//性价比表现
						JSONObject cost_effectiveness = dataObj.getJSONObject("cost_effectiveness");
						//播放数
						String play = cost_effectiveness.getString("play");
						orderDetail.setCpm(cost_effectiveness.getString("cpm"));
						orderDetail.setPlay(play);
						orderDetail.setPrice(cost_effectiveness.getString("price"));
						//创意表现
						JSONObject creative = dataObj.getJSONObject("creative");
						String finishRate = creative.getString("finish_rate");
						String fiveSPlayRate = creative.getString("five_s_play_rate");
						String playRate = creative.getString("play_rate");
						orderDetail.setFinishRate(finishRate);
						orderDetail.setFiveSPlayRate(fiveSPlayRate);
						orderDetail.setPlayRate(playRate);
						//传播表现
						JSONObject spread = dataObj.getJSONObject("spread");
						orderDetail.setSpreadComment(spread.getString("comment"));
						orderDetail.setSpreadLike(spread.getString("like"));
						orderDetail.setSpreadPlay(spread.getString("play"));
						orderDetail.setSpreadShare(spread.getString("share"));

						//完成播放次数
						Double fn = Math.ceil(BigDecimalUtils.mul(BigDecimalUtils.divide(Double.valueOf(finishRate),10000L),Double.valueOf(play)));
						orderDetail.setFinishNumber(String.valueOf(fn.intValue()));
						//有效播放数
						Double spn = Math.ceil(BigDecimalUtils.mul(BigDecimalUtils.divide(Double.valueOf(fiveSPlayRate),10000L),Double.valueOf(play)));
						orderDetail.setFiveSPlayNumber(String.valueOf(spn.intValue()));
						//平均播放数--暂时不使用 默认0
						//orderDetail.setPlayNumber(String.valueOf(Math.ceil(BigDecimalUtils.mul(BigDecimalUtils.divide(Double.valueOf(playRate),10000L),Double.valueOf(play)))));
						orderDetail.setPlayNumber("0");

						//数据更新时间，格式%Y-%m-%d %H:%M:%S
						orderDetail.setOrderUpdateTime(dataObj.getString("update_time"));

						XingtuOrderDetail xingtuOrderDetail = xingtuOrderDetailMapper.selectOne(Wrappers.<XingtuOrderDetail>lambdaQuery()
								.eq(XingtuOrderDetail::getDemandId,demandId)
								.eq(XingtuOrderDetail::getOrderId,orderId)
								.eq(XingtuOrderDetail::getAdvertiserId,startId));
						if (xingtuOrderDetail != null) {
							Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
							orderDetail.setUpdateTime(now);
							xingtuOrderDetailMapper.update(orderDetail,Wrappers.<XingtuOrderDetail>lambdaUpdate()
									.eq(XingtuOrderDetail::getDemandId,demandId)
									.eq(XingtuOrderDetail::getOrderId,orderId)
									.eq(XingtuOrderDetail::getAdvertiserId,startId));
						} else {
							xingtuOrderDetailMapper.insert(orderDetail);
						}
					} else {
						XxlJobLogger.log("获取星图订单明细异常：{},星图账户：{},订单ID：{}",resBean.getMessage(),startId,orderId);
						log.info("获取星图订单明细异常：{},星图账户：{},订单ID：{}",resBean.getMessage(),startId,orderId);
					}
				} catch (Exception e) {
					e.printStackTrace();
					XxlJobLogger.log("获取星图订单明细异常,星图账户：{},订单ID：{}",startId,orderId);
					log.info("获取星图订单明细异常,星图账户：{},订单ID：{}",startId,orderId);
				}
			});
		}
		return R.ok();
	}

	private List<TtAccesstoken> getTokenList(String adAccount){
		LambdaQueryWrapper<TtAccesstoken> query = new LambdaQueryWrapper<>();
		query.eq(TtAccesstoken::getHousekeeper,6);
		if (StringUtils.isNotBlank(adAccount)) {
			List<String> searchStarIdList = new ArrayList<>(Arrays.asList(adAccount.split(","))).stream().collect(Collectors.toList());
			query.and(wrapper -> wrapper.in(TtAccesstoken::getAdAccount,searchStarIdList));
		}
		return ttAccesstokenService.list(query);
	}

	private List<XingtuTask> taskList(String adAccount){
		LambdaQueryWrapper<XingtuTask> query = new LambdaQueryWrapper<>();
		query.eq(XingtuTask::getDeleted,0);
		if (StringUtils.isNotBlank(adAccount)) {
			List<String> searchStarIdList = new ArrayList<>(Arrays.asList(adAccount.split(","))).stream().collect(Collectors.toList());
			query.and(wrapper -> wrapper.in(XingtuTask::getAdvertiserId,searchStarIdList));
		}
		return this.list(query);
	}

	private List<XingtuOrder> orderList(String adAccount){
		LambdaQueryWrapper<XingtuOrder> query = new LambdaQueryWrapper<>();
		query.eq(XingtuOrder::getDeleted,0);
		if (StringUtils.isNotBlank(adAccount)) {
			List<String> searchStarIdList = new ArrayList<>(Arrays.asList(adAccount.split(","))).stream().collect(Collectors.toList());
			query.and(wrapper -> wrapper.in(XingtuOrder::getAdvertiserId,searchStarIdList));
		}
		return xingtuOrderMapper.selectList(query);
	}



}


